﻿using System;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Metadata.Internal;

namespace CRM.Extensions
{
    public static class DbExtension
    {
        public static void HandleDataChanged(this DbContext dbContext)
        {
            dbContext.ChangeTracker.StateChanged += UpdateTimestamps;
            dbContext.ChangeTracker.Tracked += UpdateTimestamps;
        }
        
        public static void RemoveDataChanged(this DbContext dbContext)
        {
            dbContext.ChangeTracker.StateChanged -= UpdateTimestamps;
            dbContext.ChangeTracker.Tracked -= UpdateTimestamps;
        }
        
        private static void UpdateTimestamps(object sender, EntityEntryEventArgs e)
        {
            if (e.Entry.Entity is IHasTimestamps entityWithTimestamps)
            {
                switch (e.Entry.State)
                {
                    case EntityState.Deleted:
                        //entityWithTimestamps.Deleted = DateTime.UtcNow;
                        Console.WriteLine($"Stamped for delete: {e.Entry.Entity}");
                        break;
                    case EntityState.Modified:
                        entityWithTimestamps.UpdatedAt = DateTime.Now;
                        break;
                    case EntityState.Added:
                        entityWithTimestamps.CreatedAt = DateTime.Now;
                        entityWithTimestamps.UpdatedAt = DateTime.Now;
                        break;
                }
            }
        }
        
        
        public static ModelBuilder RemoveForeignKeys(this ModelBuilder modelBuilder)
        {
            var entityTypes = modelBuilder.Model.GetEntityTypes().ToList();

            for (int i = 0; i < entityTypes.Count(); i++)
            {
                var entityType = entityTypes[i];

                var references = entityType.GetDeclaredReferencingForeignKeys().ToList();

                using (((Model)entityType.Model).Builder.Metadata.ConventionDispatcher.DelayConventions())
                {
                    foreach (var reference in references)
                    {
                        reference.DeclaringEntityType.RemoveForeignKey(reference);
                    }
                }
            }
            return modelBuilder;
        }
    }
    
    public interface IHasTimestamps
    {
        public DateTime CreatedAt { get; set; }

        public DateTime UpdatedAt { get; set; }
    }
}